///////////////////////////////////////////////////////////////////////////////
//
// Depth-First Search Maze Generator
//
// Original program written by Mike Gold, September 2005
// See Mike's page at:
// http://www.microgold.com
// Code available in MazeGenerator.ZIP from:
// http://www.gamespp.com/c/generatingMazes.html
// or from the C# Corner as dfsmaze.zip:
// http://www.c-sharpcorner.com/UploadFile/mgold/Maze09222005021857AM/Maze.aspx
//
// See also
// http://www.mazeworks.com/mazegen/mazetut/
// for an explanation of how mazes can be generated
//
// Modified by Trevor Taylor, Feb 2008
//
// Changes:
// Adjusted some of the initial parameters
// Created a separate menu item to set the maze parameters
// Renamed Form1 to MainForm
// Added a PictureBox for the Maze instead of drawing onto the Form
// (Required different handling for Paint and Resize events)
// Adjusted padding around the maze to be more even
// Added random Start and Finish cells (marked in green and red)
// (Which required a wall color parameter for drawing cells)
// Added Wall Thickness and allowed user to change it
// Added Save As menu option to save the bitmap
// Added Point-and-click to find out cell/pixel coords on the maze
// Created an icon using the generator itself
//
///////////////////////////////////////////////////////////////////////////////


using System;
using System.Drawing;

namespace DFSAlgorithmMaze
{
	/// <summary>
	/// Summary description for Cell.
	/// </summary>
	public class Cell
	{
        // TT was 10
		public static int kCellSize = 20;
        // TT was 5
        // Now forced to be equal to kCellSize, so no effect
		public static int kPadding = 20;
        // TT - Added this
        public static int WallThickness = 10;
		public int[] Walls  = new int[4]{1, 1, 1, 1};
		public int Row;
		public int Column;
		private static long Seed = 	DateTime.Now.Ticks;
		static public Random TheRandom = new Random((int)Cell.Seed);
		
		
		public Cell()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		public bool HasAllWalls()
		{
			for (int i = 0; i < 4; i++)
			{
				 if (Walls[i] == 0)
					 return false;
			}

			return true;
		}

		public void KnockDownWall(int theWall)
		{
			Walls[theWall] = 0;
		}

		public void KnockDownWall(Cell theCell)
		{
			// find adjacent wall
			int theWallToKnockDown = FindAdjacentWall(theCell);
			Walls[theWallToKnockDown] = 0;
			int oppositeWall = (theWallToKnockDown + 2) % 4;
			theCell.Walls[oppositeWall] = 0;
		}


		public  int FindAdjacentWall(Cell theCell)
		{
			if (theCell.Row == Row) 
			{
				if (theCell.Column < Column)
					return 0;
				else
					return 2;
			}
			else // columns are the same
			{
				if (theCell.Row < Row)
					return 1;
				else
					return 3;
			}
		}

		public int GetRandomWall()
		{
			int nextWall = TheRandom.Next(0, 3);
			while ( (Walls[nextWall] == 0)  
			||		((Row == 0) && (nextWall == 0)) ||
					((Row == Maze.kDimension - 1) && (nextWall == 2)) ||
					((Column == 0) && (nextWall == 1)) ||
					((Column == Maze.kDimension - 1) && (nextWall == 3)) 
				   )
			{
				nextWall = TheRandom.Next(0, 3);
			}

			return nextWall;
		}

        // TT - Add color parameter
		public void Draw(Graphics g, Color c)
		{
            // TT - Add wall thickness
            // Wall thickness should be no more than half of the grid cell size
            Pen p = new Pen(c, WallThickness);
            // Need caps to make the corners join up properly
            p.EndCap = System.Drawing.Drawing2D.LineCap.Square;
            p.StartCap = System.Drawing.Drawing2D.LineCap.Square;

			if (Walls[0] == 1)
			{
                // TT - Was this a bug?
                //g.DrawLine(p, Row * kCellSize + kPadding, Column * kCellSize + kPadding, (Row + 1) * kCellSize + kPadding, Column * kCellSize + +kPadding);
                g.DrawLine(p, Row * kCellSize + kPadding, Column * kCellSize + kPadding, (Row + 1) * kCellSize + kPadding, Column * kCellSize + kPadding);
			}
			if (Walls[1] == 1)
			{
				g.DrawLine(p, Row*kCellSize  + kPadding, Column*kCellSize + kPadding, Row*kCellSize + kPadding, (Column+1)*kCellSize + kPadding);
			}
			if (Walls[2] == 1)
			{
				g.DrawLine(p, Row*kCellSize + kPadding, (Column+1)*kCellSize + kPadding, (Row+1)*kCellSize + kPadding, (Column+1)*kCellSize + kPadding);
			}
			if (Walls[3] == 1)
			{
				g.DrawLine(p,(Row+1)*kCellSize + kPadding , Column*kCellSize + kPadding, (Row+1)*kCellSize + kPadding, (Column+1)*kCellSize + kPadding);
			}

		}
	}
}
